/*
 * @Author: xiaosihan
 * @Date: 2023-02-06 15:22:57
 * @Last Modified by: xiehangyun
 * @Last Modified time: 2025-07-24 21:11:24
 */
import { AmbientLight, DirectionalLight, PointLight, Vector3 } from 'three';
import ThreeBase from 'three-base';
import threeUtils from 'three-base/threeUtils';

import Ground1 from "three-base/Ground1";
import Sky from "three-base/Sky";
import House from './component3d/House/House';
import PointText from './component3d/PointText/PointText';
import { autorun, toJS } from 'mobx';
import homeStore from './homeStore';
import DeviceGroup from './component3d/DeviceGroup/DeviceGroup';


/**
 * @class HomeRender
 * @extends {ThreeBase}
 */
class HomeRender extends ThreeBase {
    constructor() {
        super();
        window.homeRender = this;
    }

    // 环境光
    ambientLight = (() => {
        const ambientLight = new AmbientLight('#fff', 1.5);
        this.scene.add(ambientLight);
        return ambientLight;
    })();

    //点光源
    pointLight = (() => {
        const pointLight = new PointLight('#fff', 1.5);
        pointLight.position.set(50, 40, 50);
        pointLight.shadow.bias = -0.001;
        this.scene.add(pointLight);
        return pointLight;
    })();

    // 方向光
    directionalLight = (() => {
        const directionalLight = new DirectionalLight('#fff', 1.5);
        directionalLight.position.set(-10, 10, 5);
        directionalLight.target.position.set(0, 0, 0);
        directionalLight.castShadow = true;
        directionalLight.shadow.bias = -0.001;
        directionalLight.shadow.mapSize.set(1024, 1024);
        this.scene.add(directionalLight);
        return directionalLight;
    })();

    init() {
        super.init();

        // 开发模式时还原记录的位置
        if (threeUtils.isDev && localStorage.lookAt) {
            this.resetLookAt({
                ...JSON.parse(localStorage.lookAt),
            });
        }

        // 开发模式时记录当前的位置
        if (threeUtils.isDev) {
            this.controls.addEventListener('change', () => {
                localStorage.lookAt = JSON.stringify(this.getLookAt());
            });
        }

        if (threeUtils.isProd || (threeUtils.isDev && !localStorage.lookAt)) {
            this.resetLookAt({
                center: new Vector3(0.851, -18.694, 20.774),
                position: new Vector3(68.123, 88.587, 152.442)
            });
        }
    }

    // 装饰地面
    ground = (() => {
        const ground = new Ground1();
        ground.position.set(0, -1, 0);
        ground.setSize(2000, 2000);
        this.scene.add(ground);
        return ground;
    })();

    sky = (() => {
        const sky = new Sky();
        this.scene.add(sky);
        return sky;
    })();

    // 房屋模型
    house = (() => {
        const house = new House();
        house.position.set(0, 0, 0);
        this.scene.add(house);
        return house;
    })();

    // 点位文字
    pointText1 = (() => {
        const pointText = new PointText("楼1");
        pointText.position.set(37.99, 23, 37.30);
        this.add(pointText);
        return pointText;
    })();

    // 点位文字
    pointText2 = (() => {
        const pointText = new PointText("楼2");
        pointText.position.set(-63.07, 23, 35.597);
        this.add(pointText);
        return pointText;
    })();

    // 点位文字
    pointText3 = (() => {
        const pointText = new PointText("楼2");
        pointText.position.set(-13.30, 41.26, 12.192);
        this.add(pointText);
        return pointText;
    })();

    // 设备配置
    deviceGroup = (() => {
        const deviceGroup = new DeviceGroup();
        deviceGroup.addEventListener("click", e => {
            this.dispatchEvent(e as never);
        });
        this.scene.add(deviceGroup);
        return deviceGroup;
    })();

    // 监听楼层变化
    dispose1 = autorun(() => {
        switch (homeStore.showFlor) {
            case 1:
                this.setLookAt({
                    center: new Vector3(-13.312, -8.838, 3.252),
                    position: new Vector3(-12.764, 49.182, 36.366)
                })
                break;
            case 2:
                this.setLookAt({
                    center: new Vector3(-13.312, -6.838, 3.252),
                    position: new Vector3(-12.764, 51.182, 36.366)
                })
                break;
            case 3:
                this.setLookAt({
                    center: new Vector3(-13.312, -4.838, 3.252),
                    position: new Vector3(-12.764, 53.182, 36.366)
                })
                break;
            case 4:
                this.setLookAt({
                    center: new Vector3(-13.312, -2.838, 3.252),
                    position: new Vector3(-12.764, 55.182, 36.366)
                })
                break;
            case 5:
                this.setLookAt({
                    center: new Vector3(-13.312, -0.838, 3.252),
                    position: new Vector3(-12.764, 57.182, 36.366)
                })
                break;
            case 6:
                this.setLookAt({
                    center: new Vector3(-13.312, 0.162, 3.252),
                    position: new Vector3(-12.764, 59.182, 36.366)
                })
                break;
            case 7:
                this.setLookAt({
                    center: new Vector3(-13.312, 1.162, 3.252),
                    position: new Vector3(-12.764, 61.182, 36.366)
                })
                break;
            default:
                this.setLookAt({
                    center: new Vector3(0.851, -18.694, 20.774),
                    position: new Vector3(68.123, 88.587, 152.442)
                });
                break;
        }
    })

    //监听设备数据
    dispose2 = autorun(() => {
        const deviceData = toJS(homeStore.deviceDatas);
        this.deviceGroup.setDeviceDatas(deviceData);
    });

    //默认视角
    defaultLookAt = () => {
        this.setLookAt({
            center: new Vector3(0.851, -18.694, 20.774),
            position: new Vector3(68.123, 88.587, 152.442)
        });
    }

    // 设看制定设备
    lookAtDevice(deviceId: string) {

        const { center, position } = this.getLookAt();
        const direction = position.clone().sub(center).setLength(5);

        const deviceData = homeStore.deviceDatas.find(d => d.id === deviceId);
        if (deviceData) {
            const { x, y, z } = deviceData;
            this.setLookAt({
                center: new Vector3(x, y, z),
                position: new Vector3(x + direction.x, y + direction.y, z + direction.z)
            });
        }
    }

}

const homeRenderer = new HomeRender();

export default homeRenderer;
